//==============================================================
/**
 * @description VMP管理
 * @author Brave Chan on 2019.5
 * @version 1.0.3
 */
//==============================================================
import VMP from './ViewModelProxy';
import { VMO_ID } from './vmpconst';
import { isFunction } from '../utils/util';
import { addVMP, getVMPs, removeVMP, hasVMP } from './proxyCollect';
import { setDebug, setUpdateInterval } from './updateProxys';
import Log from '../tools/BELog';
import { APP_TYPE, PAGE_TYPE, COMPONENT_TYPE } from '../constant/nodeType';
//==============================================================
let _debug = false;
//==============================================================
/**
 * @private
 * @description 创建vmp实例
 * @param {object} master [required] 宿主对象
 * @returns {VMP} 代理对象
 */
function createVMP(master) {
  let vmp = new VMP(master);
  vmp.debug = _debug;
  master[VMO_ID] = vmp.id;
  addVMP(vmp);
  return vmp;
}

const onShowHandlers = {
  [APP_TYPE]() {
    // 恢复并启动一次全部的延迟属性渲染
  },
  [PAGE_TYPE]() {
    // 恢复并启动一次页面的延迟属性渲染
  },
  [COMPONENT_TYPE]() {
    // 恢复并启动组件的延迟属性渲染
  }
};

const onHideHandlers = {
  [APP_TYPE]() {
    // 暂停全部延迟属性渲染
  },
  [PAGE_TYPE]() {
    // 暂停此页面的延迟属性渲染
  },
  [COMPONENT_TYPE]() {
    // 暂停此组件的延迟属性渲染
  }
};

//==============================================================
export default {
  get moduleName() {
    return 'vmp';
  },
  get debug() {
    return _debug;
  },
  set debug(value) {
    _debug = !!value;
    setDebug(_debug);
  },
  set interval(value) {
    setUpdateInterval(value || 100);
  },
  get interval() {
    return _interval;
  },
  get be_vmList() {
    return getVMPs();
  },
  get isVMP() {
    return true;
  },
  /**
   * @description 模块生命周期-启动
   * @param {*} config
   */
  setup(config) {
    this.debug = config.debug;

    return {
      'VMP': getVMPs
    };
  },
  /**
   * @description 模块生命周期-解析原始声明对象
   * @param {any} origin 原始的声明对象。由于此对象将来会销毁。请不要保留他的引用。
   * @param {number} 当前声明对象发起的类型，1为App，2为Page，3为Component
   */
  originParse(origin, type, master) {
    if (type === 0) {
      return;
    }
    master._be_vmp = null;
  },
  /**
   * @description 模块生命周期-初始化vmp
   * @param {*} master
   */
  initVMP(master) {
    if (!master) {
      if (_debug) {
        throw new Error('In beStates initVMP(), can not get the master.');
      }

      Log.error('In beStates initVMP(), can not get the master. typeof master==>', typeof master);

      return {
        isError: true,
        message: 'Can not find the master'
      };
    }
    let vmp = createVMP(master);
    master._be_vmp = vmp;
    return vmp;
  },
  /**
   * @description 模块生命周期-解析，解析页面或者组件的data
   * @param {*} master
   * @param {*} vmp
   */
  parse(master = {}, vmp = {}) {
    if (!master.data) {
      return;
    }

    let props = Object.keys(master.data).reduce(function(prev, item) {
      prev[item] = {
        get() {
          return this.data[item];
        },
        set(value) {
          if (this && this._be_vmp) {
            this.commit(item, value);
          } else {
            if (_debug) {
              Log.error('In VMP beStates parse(), can not find the master or vmp', this._beID, this[VMO_ID]);
            }
          }
        }
      };
      return prev;
    }, {});
    Object.defineProperties(master, props);
  },
  /**
   * @description 模块生命周期-装饰，装饰app,页面或组件的vm
   * @param {*} master
   * @param {*} vmp
   */
  decorate(master, vmp) {
    if (!master.data) {
      return;
    }
    // 提交
    master.commit = function(...args) {
      if (this && this._be_vmp) {
        this._be_vmp.commit.apply(this._be_vmp, args);
      } else {
        if (_debug) {
          Log.error('In VMP beStates decorate() master.commit, can not find the master or vmp', this._beID, this[VMO_ID]);
        }
      }
    };

    // 立即生效
    master.validateNow = function() {
      if (this && this._be_vmp) {
        this._be_vmp.validateNow();
      } else {
        if (_debug) {
          Log.error('In VMP beStates decorate() master.validateNow, can not find the master or vmp', this._beID, this[VMO_ID]);
        }
      }
    };
  },
  /**
   * @description 试验方法，模块生命周期-进入后台
   * @param {*} master
   * @param {*} vmp
   */
  onShow(master, vmp) {
    let type = master._beNodeType;
    let fn = onShowHandlers[type];
    if (isFunction(fn)) {
      fn(vmp);
    }
  },
  /**
   * @description 试验方法，模块生命周期-回到前台
   * @param {*} master
   * @param {*} vmp
   */
  onHide(master, vmp) {
    let type = master._beNodeType;
    let fn = onHideHandlers[type];
    if (isFunction(fn)) {
      fn(vmp);
    }
  },
  /**
   * @description 模块生命周期-清洗
   * @param {*} master
   * @param {*} vmp
   */
  wash(master, vmp) {
    if (isFunction(master.commit)) {
      master.commit = null;
    }

    if (isFunction(master.validateNow)) {
      master.validateNow = null;
    }
  },
  /**
   * @description 模块生命周期-销毁vmp
   * @param {*} master
   * @param {*} vmp
   */
  destroyVMP(master, vmp) {
    let id = vmp.id;
    if (!hasVMP(id)) {
      return;
    }
    removeVMP(id);
    master[VMO_ID] = null;
    master._be_vmp = null;
    vmp.destroy();
  }
};
//==============================================================
